package com.leetcode.根据数据结构分类.栈;

import java.util.ArrayDeque;
import java.util.HashMap;

/**
 * @author: ZhouBert
 * @date: 2021/3/11
 * @description: 227. 基本计算器 II
 * https://leetcode-cn.com/problems/basic-calculator-ii/
 * {@link C_224_基本计算器}
 * 区别在于 少了括号，多了乘除
 */
public class B_227_基本计算器II {

	static B_227_基本计算器II action = new B_227_基本计算器II();

	public static void main(String[] args) {
		//ffmpeg -i https://vodpub1.v.news.cn/original/20210308/59f4c0ca42204d69b1d0a7677fe88c8d.mp4 -s qvga -b 384k -vcodec libx264 -r 23.976 -acodec libfaac -ac 2 -ar 44100 -ab 64k -vpre baseline -crf 22 -deinterlace -o YOUR-OUTPUT.MP4

		//ffmpeg -i https://vodpub1.v.news.cn/original/20210308/59f4c0ca42204d69b1d0a7677fe88c8d.mp4 -s 320x240 -r 30000/1001 -b 200k -bt 240k -vcodec libx264 -coder 0 -bf 0 -refs 1 -flags2 -wpred -dct8x8 -level 30 -maxrate 10M -bufsize 10M -acodec libfaac -ac 2 -ar 48000 -ab 192k OUTPUTx.mp4
		//
		//"3+2*2"
//		test1();
//		test2();
		test3();
	}

	static void test1() {
		// 7
		String str = "3+2*2";
		int res = action.calculate(str);
		System.out.println(res);
	}

	static void test2() {
		// 1
		String str = " 3/2 ";
		int res = action.calculate(str);
		System.out.println(res);
	}

	static void test3() {
		// 3
		String str = "1+1+1";
		int res = action.calculate(str);
		System.out.println(res);
	}


	/**
	 * 如果木有括号是可以直接计算的；
	 * 总感觉这样写的还是不够精炼
	 * @param s
	 * @return
	 */
	public int calculate(String s) {
		HashMap<Character, Integer> map = new HashMap<>(4);
		initMap(map);

		char[] chars = s.toCharArray();
		int len = chars.length;
		ArrayDeque<Integer> digitDeque = new ArrayDeque<>();
		ArrayDeque<Character> opeDeque = new ArrayDeque<>();
		int value = 0;
		boolean isDigit = false;
		for (int i = 0; i < len; i++) {
			char c = chars[i];
			if (Character.isDigit(c)) {
				value = value * 10 + Character.getNumericValue(c);
				isDigit = true;
			} else {
				//只有当 c 是个运算符时，才需要考虑 先前的操作
				//首先处理入栈（简化代码流程）
				if (isDigit == true) {
					digitDeque.addLast(value);
				}
				if (c == ' ') {

				} else {
					if (opeDeque.isEmpty()) {
						opeDeque.addLast(c);
					} else {
						if (map.get(c) <= map.get(opeDeque.peekLast())) {
							do {
								int second = digitDeque.removeLast();
								int first = digitDeque.removeLast();
								int cal = cal(first, opeDeque.removeLast(), second);
								digitDeque.addLast(cal);
							} while (!opeDeque.isEmpty()&& map.get(c) <= map.get(opeDeque.peekLast()));
						}
						opeDeque.addLast(c);
						if (digitDeque.isEmpty()) {
							digitDeque.addLast(0);
						}
					}
				}
				value = 0;
				isDigit = false;
			}
		}
		if (!isDigit){
			value = digitDeque.removeLast();
		}
		//再次计算剩余的
		while (!opeDeque.isEmpty()) {
			char op = opeDeque.removeLast();
			int first = digitDeque.removeLast();
			value = cal(first, op, value);
		}
		return digitDeque.isEmpty() ? value : digitDeque.removeFirst();
	}

	private int cal(int first, char op, int second) {
		int res = 0;
		switch (op) {
			case '+':
				res = first + second;
				break;
			case '-':
				res = first - second;
				break;
			case '*':
				res = first * second;
				break;
			case '/':
				res = first / second;
				break;
		}
		return res;
	}

	private void initMap(HashMap<Character, Integer> map) {
		map.put('+', 0);
		map.put('-', 0);
		map.put('*', 1);
		map.put('/', 1);
	}
}
